/*
 *    Copyright (c) 2018-2025, haohanwork.com All rights reserved.
 */
package com.haohan.cloud.scm.goods.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.haohan.cloud.scm.api.common.tree.TreeNode;
import com.haohan.cloud.scm.api.common.tree.TreeUtil;
import com.haohan.cloud.scm.api.goods.entity.CategoryRelation;
import com.haohan.cloud.scm.goods.mapper.CategoryRelationMapper;
import com.haohan.cloud.scm.goods.service.CategoryRelationService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 分类关系表
 *
 * @author haohan
 * @date 2020-04-08 17:47:17
 */
@Service
public class CategoryRelationServiceImpl extends ServiceImpl<CategoryRelationMapper, CategoryRelation> implements CategoryRelationService {


    @Override
    public void insertCategoryRelation(String id, String parentId, Class clazz) {
        //增加层级关系表  父节点的所有父级
        List<CategoryRelation> relationList = baseMapper
                .selectList(Wrappers.<CategoryRelation>query().lambda()
                        .eq(CategoryRelation::getDescendant, parentId)
                        .eq(CategoryRelation::getClassName, clazz.getSimpleName())
                )
                .stream().peek(relation -> {
                    relation.setDescendant(id);
                    relation.setId(null);
                    relation.setTenantId(null);
                }).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(relationList)) {
            this.saveBatch(relationList);
        }
        //自己也要维护到关系表中
        if (!TreeUtil.ROOT.equals(parentId)) {
            CategoryRelation own = new CategoryRelation();
            own.setDescendant(id);
            own.setAncestor(parentId);
            own.setClassName(clazz.getSimpleName());
            baseMapper.insert(own);
        }
    }

    /**
     * 删除所有 选择ids中 对应的关联关系
     *
     * @param ids   需删除的id集合
     * @param clazz
     */
    @Override
    public void deleteAllCategoryRelation(Collection<String> ids, Class clazz) {
        // 删除所有
        baseMapper.delete(Wrappers.<CategoryRelation>query().lambda()
                .eq(CategoryRelation::getClassName, clazz.getSimpleName())
                .and(q -> q.in(CategoryRelation::getAncestor, ids)
                        .or()
                        .in(CategoryRelation::getDescendant, ids)
                )
        );
    }

    @Override
    public void updateCategoryRelation(CategoryRelation relation) {
        String className = relation.getClassName();
        // 当前子节点的 所有父节点
        Set<String> parentSet = fetchAllAncestor(relation.getDescendant(), className);
        // 当前子节点的 所有子节点
        Set<String> childSet = fetchAllDescendant(relation.getDescendant(), className);
        childSet.add(relation.getDescendant());
        // 存在父节点时  删除所有父子节点对应的数据
        if (CollUtil.isNotEmpty(parentSet)) {
            baseMapper.delete(Wrappers.<CategoryRelation>query().lambda()
                    .eq(CategoryRelation::getClassName, className)
                    .in(CategoryRelation::getAncestor, parentSet)
                    .in(CategoryRelation::getDescendant, childSet)
            );
        }
        // 新增 子、父节点 对应的关系
        // 当前父节点的 所有父节点
        Set<String> ancestorSet = fetchAllAncestor(relation.getAncestor(), className);
        if (!TreeUtil.ROOT.equals(relation.getAncestor())) {
            ancestorSet.add(relation.getAncestor());
        }
        ancestorSet.forEach(parent -> childSet.forEach(child -> {
            CategoryRelation categoryRelation = new CategoryRelation();
            categoryRelation.setClassName(className);
            categoryRelation.setAncestor(parent);
            categoryRelation.setDescendant(child);
            baseMapper.insert(categoryRelation);
        }));
    }

    /**
     * 更新实体类的所有关联关系(删除所有原关系数据)
     *
     * @param treeNodeList 所有需创建的关系树节点对象
     * @param clazz
     * @param <E>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public <E extends TreeNode> void updateAllRelation(List<E> treeNodeList, Class clazz) {
        // 删除所有
        String className = clazz.getSimpleName();
        baseMapper.delete(Wrappers.<CategoryRelation>query().lambda()
                .eq(CategoryRelation::getClassName, className)
        );
        List<TreeNode> list = TreeUtil.buildAllRelation(treeNodeList);
        list.forEach(item -> {
            CategoryRelation relation = new CategoryRelation();
            relation.setClassName(className);
            relation.setDescendant(item.getId());
            relation.setAncestor(item.getParentId());
            baseMapper.insert(relation);
        });
    }

    /**
     * 查询所有后代节点
     *
     * @param ancestor
     * @param className
     * @return
     */
    @Override
    public Set<String> fetchAllDescendant(String ancestor, String className) {
        return baseMapper.selectList(Wrappers.<CategoryRelation>query().lambda()
                .eq(CategoryRelation::getAncestor, ancestor)
                .eq(CategoryRelation::getClassName, className)
        ).stream()
                .map(CategoryRelation::getDescendant)
                .collect(Collectors.toSet());
    }

    /**
     * 查询所有祖先节点
     *
     * @param descendant
     * @param className
     * @return
     */
    @Override
    public Set<String> fetchAllAncestor(String descendant, String className) {
        return baseMapper.selectList(Wrappers.<CategoryRelation>query().lambda()
                .eq(CategoryRelation::getDescendant, descendant)
                .eq(CategoryRelation::getClassName, className)
        ).stream()
                .map(CategoryRelation::getAncestor)
                .collect(Collectors.toSet());
    }
}
